package com.lucifer.treasure.enchant.effect;

import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.entity.Entity;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Vec3d;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public record ReachEnchantmentEffect(EnchantmentLevelBasedValue reach) implements EnchantmentEntityEffect {
    public static final MapCodec<ReachEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
            instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("reach").forGetter(ReachEnchantmentEffect::reach)
            ).apply(instance, ReachEnchantmentEffect::new)
    );

    // 唯一ID用于属性修改器
    private static final Identifier REACH_MODIFIER_ID = Identifier.of("lucifer_treasure", "reach_enchantment");

    // 使用内存存储而不是NBT，避免持久化问题
    private static final Map<UUID, Integer> playerReachLevels = new HashMap<>();

    // 等级对应的reach增加量 (原版reach大约是5，这些值会加到上面)
    private static final int[] REACH_LEVELS = {0, 1, 2, 3, 4, 5}; // 简化版本

    public static void initialize() {
        ServerTickEvents.END_SERVER_TICK.register(server -> {
            server.getPlayerManager().getPlayerList().forEach(player -> {
                updatePlayerReach(player);
            });
        });
    }

    /**
     * 更新玩家的reach属性
     */
    private static void updatePlayerReach(PlayerEntity player) {
        int currentLevel = getReachLevelFromWeapon(player);
        int storedLevel = getStoredReachLevel(player);

        // 如果等级发生变化，更新属性
        if (currentLevel != storedLevel) {
            removeReachModifier(player);

            if (currentLevel > 0) {
                addReachModifier(player, currentLevel);
            }

            setStoredReachLevel(player, currentLevel);
        }
    }

    /**
     * 从玩家武器获取Reach附魔等级
     */
    private static int getReachLevelFromWeapon(PlayerEntity player) {
        int maxLevel = 0;

        // 检查主手和副手武器
        maxLevel = Math.max(maxLevel, getReachLevelFromStack(player.getMainHandStack()));
        maxLevel = Math.max(maxLevel, getReachLevelFromStack(player.getOffHandStack()));

        return maxLevel;
    }

    /**
     * 从物品栈获取Reach附魔等级
     */
    private static int getReachLevelFromStack(ItemStack stack) {
        if (stack.isEmpty()) {
            return 0;
        }

        var enchantments = EnchantmentHelper.getEnchantments(stack);
        int maxLevel = 0;

        for (var entry : enchantments.getEnchantments()) {
            if (entry.getKey().isPresent()) {
                String enchantmentId = entry.getKey().get().getValue().toString();
                if (enchantmentId.equals("lucifer_treasure:reach")) {
                    maxLevel = Math.max(maxLevel, enchantments.getLevel(entry));
                }
            }
        }

        return maxLevel;
    }

    /**
     * 添加reach属性修改器
     */
    private static void addReachModifier(PlayerEntity player, int level) {
        double reachIncrease = getReachBoost(level);

        // 创建属性修改器
        EntityAttributeModifier reachModifier = new EntityAttributeModifier(
                REACH_MODIFIER_ID,
                reachIncrease,
                EntityAttributeModifier.Operation.ADD_VALUE
        );

        // 添加到玩家属性
        var reachAttribute = player.getAttributeInstance(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE);
        if (reachAttribute != null && !reachAttribute.hasModifier(REACH_MODIFIER_ID)) {
            reachAttribute.addTemporaryModifier(reachModifier);
        }

        var entityReachAttribute = player.getAttributeInstance(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE);
        if (entityReachAttribute != null && !entityReachAttribute.hasModifier(REACH_MODIFIER_ID)) {
            entityReachAttribute.addTemporaryModifier(reachModifier);
        }
    }

    /**
     * 移除reach属性修改器
     */
    private static void removeReachModifier(PlayerEntity player) {
        var reachAttribute = player.getAttributeInstance(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE);
        if (reachAttribute != null) {
            reachAttribute.removeModifier(REACH_MODIFIER_ID);
        }

        var entityReachAttribute = player.getAttributeInstance(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE);
        if (entityReachAttribute != null) {
            entityReachAttribute.removeModifier(REACH_MODIFIER_ID);
        }
    }

    /**
     * 计算reach增加量
     */
    private static double getReachBoost(int level) {
        if (level <= 0) {
            return 0;
        }
        if (level < REACH_LEVELS.length) {
            return REACH_LEVELS[level];
        }
        // 对于超高级别的支持
        int extraLevels = level - REACH_LEVELS.length + 1;
        return REACH_LEVELS[REACH_LEVELS.length - 1] + extraLevels;
    }

    /**
     * 获取存储的reach等级
     */
    private static int getStoredReachLevel(PlayerEntity player) {
        return playerReachLevels.getOrDefault(player.getUuid(), 0);
    }

    /**
     * 设置存储的reach等级
     */
    private static void setStoredReachLevel(PlayerEntity player, int level) {
        if (level == 0) {
            playerReachLevels.remove(player.getUuid());
        } else {
            playerReachLevels.put(player.getUuid(), level);
        }
    }

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        // 主要逻辑在服务器tick事件中处理
        // 这个方法保留用于其他可能的触发方式
        if (target instanceof PlayerEntity player) {
            updatePlayerReach(player);
        }
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
} 